// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraCharacterMovementComponent.h"
// 包含头文件

#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "Components/CapsuleComponent.h"
#include "Engine/World.h"
#include "GameFramework/Character.h"
// 包含相关依赖头文件

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraCharacterMovementComponent)
// 包含内联生成的C++代码

UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_MovementStopped, "Gameplay.MovementStopped");
// 定义游戏标签 TAG_Gameplay_MovementStopped

namespace LyraCharacter
{
	static float GroundTraceDistance = 100000.0f;
	// 地面检测距离，默认100米
	FAutoConsoleVariableRef CVar_GroundTraceDistance(TEXT("LyraCharacter.GroundTraceDistance"), GroundTraceDistance, TEXT("Distance to trace down when generating ground information."), ECVF_Cheat);
	// 控制台变量，可在运行时调整地面检测距离，标记为作弊变量
};

ULyraCharacterMovementComponent::ULyraCharacterMovementComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}
// 构造函数，调用父类构造函数

void ULyraCharacterMovementComponent::SimulateMovement(float DeltaTime)
{
	if (bHasReplicatedAcceleration)
	{
		// Preserve our replicated acceleration
		const FVector OriginalAcceleration = Acceleration;
		// 保存当前加速度
		Super::SimulateMovement(DeltaTime);
		// 调用父类模拟移动
		Acceleration = OriginalAcceleration;
		// 恢复复制的加速度
	}
	else
	{
		Super::SimulateMovement(DeltaTime);
		// 正常调用父类模拟移动
	}
}

bool ULyraCharacterMovementComponent::CanAttemptJump() const
{
	// Same as UCharacterMovementComponent's implementation but without the crouch check
	return IsJumpAllowed() &&
		(IsMovingOnGround() || IsFalling()); // Falling included for double-jump and non-zero jump hold time, but validated by character.
	// 与父类实现相同但不检查下蹲状态，允许在地面或空中跳跃（用于二段跳）
}

void ULyraCharacterMovementComponent::InitializeComponent()
{
	Super::InitializeComponent();
	// 调用父类组件初始化
}

const FLyraCharacterGroundInfo& ULyraCharacterMovementComponent::GetGroundInfo()
{
	if (!CharacterOwner || (GFrameCounter == CachedGroundInfo.LastUpdateFrame))
	{
		return CachedGroundInfo;
	}
	// 如果没有角色所有者或当前帧已更新，返回缓存的地面信息

	if (MovementMode == MOVE_Walking)
	{
		// 如果当前移动模式是行走
		CachedGroundInfo.GroundHitResult = CurrentFloor.HitResult;
		// 使用当前地板检测结果
		CachedGroundInfo.GroundDistance = 0.0f;
		// 地面距离为0
	}
	else
	{
		const UCapsuleComponent* CapsuleComp = CharacterOwner->GetCapsuleComponent();
		check(CapsuleComp);
		// 获取胶囊体组件并验证

		const float CapsuleHalfHeight = CapsuleComp->GetUnscaledCapsuleHalfHeight();
		// 获取胶囊体半高
		const ECollisionChannel CollisionChannel = (UpdatedComponent ? UpdatedComponent->GetCollisionObjectType() : ECC_Pawn);
		// 获取碰撞通道
		const FVector TraceStart(GetActorLocation());
		// 检测起点为角色位置
		const FVector TraceEnd(TraceStart.X, TraceStart.Y, (TraceStart.Z - LyraCharacter::GroundTraceDistance - CapsuleHalfHeight));
		// 检测终点向下延伸检测距离+胶囊体半高

		FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(LyraCharacterMovementComponent_GetGroundInfo), false, CharacterOwner);
		// 创建碰撞查询参数
		FCollisionResponseParams ResponseParam;
		// 创建碰撞响应参数
		InitCollisionParams(QueryParams, ResponseParam);
		// 初始化碰撞参数

		FHitResult HitResult;
		// 声明碰撞结果
		GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, CollisionChannel, QueryParams, ResponseParam);
		// 执行射线检测

		CachedGroundInfo.GroundHitResult = HitResult;
		// 保存碰撞结果
		CachedGroundInfo.GroundDistance = LyraCharacter::GroundTraceDistance;
		// 初始设置为最大检测距离

		if (MovementMode == MOVE_NavWalking)
		{
			// 如果是导航行走模式
			CachedGroundInfo.GroundDistance = 0.0f;
			// 地面距离为0
		}
		else if (HitResult.bBlockingHit)
		{
			// 如果检测到阻挡
			CachedGroundInfo.GroundDistance = FMath::Max((HitResult.Distance - CapsuleHalfHeight), 0.0f);
			// 计算实际地面距离（碰撞距离-胶囊体半高）
		}
	}

	CachedGroundInfo.LastUpdateFrame = GFrameCounter;
	// 更新最后更新帧数

	return CachedGroundInfo;
	// 返回地面信息
}

void ULyraCharacterMovementComponent::SetReplicatedAcceleration(const FVector& InAcceleration)
{
	bHasReplicatedAcceleration = true;
	// 标记有复制的加速度
	Acceleration = InAcceleration;
	// 设置加速度值
}

FRotator ULyraCharacterMovementComponent::GetDeltaRotation(float DeltaTime) const
{
	if (UAbilitySystemComponent* ASC = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner()))
	{
		// 获取能力系统组件
		if (ASC->HasMatchingGameplayTag(TAG_Gameplay_MovementStopped))
		{
			// 如果拥有"移动停止"标签
			return FRotator(0,0,0);
			// 返回零旋转
		}
	}

	return Super::GetDeltaRotation(DeltaTime);
	// 否则调用父类实现
}

float ULyraCharacterMovementComponent::GetMaxSpeed() const
{
	if (UAbilitySystemComponent* ASC = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner()))
	{
		// 获取能力系统组件
		if (ASC->HasMatchingGameplayTag(TAG_Gameplay_MovementStopped))
		{
			// 如果拥有"移动停止"标签
			return 0;
			// 返回零速度
		}
	}

	return Super::GetMaxSpeed();
	// 否则调用父类实现
}